#include <iostream>
#include <vsomeip\vsomeip.hpp>
#include <memory>
#include <thread>

#define SERVICE_ID 0x1234
#define SERVICE_INSTANCE_ID 0x5678
#define METHOD_ID 0x0001
#define SERVICE_SET_METHOD_ID 0x0002
#define SERVICE_GET_METHOD_ID 0x0003
#define SERVICE_EVENT_GROUP_ID 0x4465
#define SERVICE_EVENT_ID 0x8778

using namespace std;
using namespace vsomeip;

shared_ptr<application> app;

void on_available(service_t _s, instance_t _ins, bool is_available)
{
    cout << "zhangjingcheng thread_id: " << std::this_thread::get_id() << " server: " << std::hex << "[" << _s << "." << _ins << "]" << (is_available ? "available" : "not available") << endl;

    if (!is_available) return;

    std::set<vsomeip::eventgroup_t> its_groups;
    its_groups.insert(SERVICE_EVENT_GROUP_ID);
    app->request_event(SERVICE_ID, SERVICE_INSTANCE_ID, SERVICE_EVENT_ID, its_groups, true);
    app->subscribe(SERVICE_ID, SERVICE_INSTANCE_ID, SERVICE_EVENT_GROUP_ID);
}

void on_message(std::shared_ptr<vsomeip::message> msg)
{
    cout << "zhangjingcheng thread_id: " << std::this_thread::get_id() << endl;
    auto server_id = msg->get_service();
    auto instance_id = msg->get_instance();
    auto method_id = msg->get_method();

    std::string str("Receive: ");
    str.append(reinterpret_cast<const char*>(msg->get_payload()->get_data()), 0, msg->get_payload()->get_length());

    std::cout << str << " method_id: " << method_id << std::endl;
}

int main()
{
    app = runtime::get()->create_application("client_sample");
    app->init();
    app->register_message_handler(vsomeip::ANY_SERVICE, vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, std::bind(&on_message, std::placeholders::_1));

    app->register_availability_handler(SERVICE_ID, SERVICE_INSTANCE_ID, on_available);
    app->request_service(SERVICE_ID, SERVICE_INSTANCE_ID);

    std::cout << "start..." << std::endl;
    std::thread t = thread(std::bind(&application::start, app));
    std::cout << "start... done" << std::endl;
    cout << "zhangjingcheng main thread_id: " << std::this_thread::get_id() << endl;
    t.join();
    return 0;
}